package c.x.jy.redislock;

import java.lang.reflect.Field;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
//import org.springframework.test.context.junit4.SpringRunner;

import sun.misc.Unsafe;
// @RunWith(SpringRunner.class)
@SuppressWarnings("all")
@SpringBootTest

public class DemoCas<T> {
	  private volatile T value;
	  static int i = 0;
	//Lock lock=new AloneLock();
	// Unsafe unsafe = Unsafe.getUnsafe()//不能直接使用，需要通过反射来获取
	static Unsafe unsafe; // java 中操作内存的一个类
	static long valueOffset; // 内存中的地址(偏移量)
	static {
		try {// 通过反射机制去拿unsafe
			Field filed = Unsafe.class.getDeclaredField("theUnsafe"); // 拿到theUnsafe
			filed.setAccessible(true); // 因为是私有，设置成可访问
			// 拿到unsafe 参数是要传一个对象，因为是静态的，没有对象所以传Null
			unsafe = (Unsafe) filed.get(null);
			// 通过数据去拿到内存中的i地址（偏移量）
			// 直接操作内存，获取属性的偏移量（同它来定位对象内具体属性的内存地址）
		//	valueOffset =   unsafe .objectFieldOffset(DemoCas.class.getDeclaredField("i"));
			  valueOffset = unsafe.objectFieldOffset  (DemoCas.class.getDeclaredField("value"));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void incr() {
		// 比较和替换
		int current = 0;// 内存中的值,当前值
		do {
			current = unsafe.getIntVolatile(this, valueOffset); // 获取当前内存中的值
		} while (!unsafe.compareAndSwapInt(this, valueOffset, current, current + 1));

	}

	public Long addi(){
		
		String id=lock.getRequestId();
		
		lock.lock(id);
		try {
			i++;
		//	System.out.println("i==="+i);
		} finally {
			lock.unlock( id );
		}
		
		if(i==1000)return System.currentTimeMillis();
		return 0l;
				
	}
	
	  /**
     * Gets the current value.
     *
     * @return the current value
     */
    public final T get() {
        return value;
    }

    /**
     * Sets to the given value.
     *
     * @param newValue the new value
     */
    public final void set(T newValue) {
        value = newValue;
    }

	private DistributedLock1 lock=new DistributedLock1( "xxx" );
	@Test
	public   void main( ) {
	//	final DemoCas demo = new DemoCas();
	 
	  final long	begin =System.currentTimeMillis();
		for (int i = 0; i < 1000; i++) {
		 
			//Jedis jedis =JedisUtil.getResource();
		 	//System.out.println(jedis.lpush("list",i+""));
		 	
		 	//jedis.close();	
			new Thread(new Runnable() {
				@Override
				public void run() {
					DemoCas demo = new DemoCas();
					for (int j = 0; j < 1; j++) {
						//demo.incr();
					 	long end =demo.addi();
					 	
					  
					 	
						 if(end>0){
						//	 Jedis jedis =JedisUtil.getResource();
							 System.out.println("执行时间："+(end -begin));
							System.out.println("i=" + demo.i);
						//	List<String > list=jedis.lrange("list", 0, -1);
							//System.out.println(list);
						//	System.out.println( jedis.lrange("lmykey", (list.size()-1) ,-1));
							//jedis.close();	
						 }
						 
						
					}
				}
			}).start();
		}
		/*try {
			 Thread.sleep(5000);
		 	System.out.println("i=" + demo.i);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
*/
	}

	public boolean compareAndSet(T v, T update) {
		   return unsafe.compareAndSwapObject(this, valueOffset, v, update);
	}

}
